using Framework;
using Framework.DataTable;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Unity.Collections;
using UnityEngine;

public partial class TableManager
{
    private Dictionary<string, TableConfig> _configs;
    public int LoadCount { get; private set; }
    public IEnumerator Load(ResLoader loader)
    {
        LoadCount = 0;
        //设置语言
        this.Lang.Branch = "ch";
        // this.Lang.SetDecodeCountPreFrame(1000);
        //加载文件大小描述
        var sizefile = "Assets/Res/DataTable/manifest.txt";
        Dictionary<string, int> sizeDict = new Dictionary<string, int>();
        var asset = loader.LoadAsset(sizefile);
        yield return asset;
        loader.Unload(asset);
        if (asset.Asset is TextAsset sizeAsset)
        {
            var lst = sizeAsset.text.Split('\n');
            foreach (var item in lst)
            {
                var kv = item.Split(':');
                var k = kv[0].Split("@")[0];
                int.TryParse(kv[1], out int size);
                if (!sizeDict.TryGetValue(k, out int s))
                {
                    sizeDict.Add(k, size);
                }
                else
                {
                    if (s < size)
                    {
                        sizeDict[k] = size;
                    }
                }
            }

        }
        _configs = new Dictionary<string, TableConfig>();
        var list = new List<TableConfig>();
        var len = this.Count;
        int fileSize = 0;
        ByteArray bigBuffer = null;
        while (len-- > 0)
        {
            var tableLoader = GetLoader(len);
            var cfg = new TableConfig();
            _configs.Add(tableLoader.GetTableName(), cfg);
            list.Add(cfg);
            cfg.Loader = tableLoader;

            if (sizeDict.TryGetValue(tableLoader.GetTableName(), out int size))
            {
                cfg.Size = size;
                if (tableLoader.LazyDecode())
                {
                    //运行时读取要保存buffer
                    var loadbuffer = new ByteArray(size);
                    cfg.Buffer = loadbuffer;
                    if (bigBuffer == null)
                    {
                        bigBuffer = loadbuffer;
                    }
                    else
                    {
                        if (bigBuffer.Buffer.Length < loadbuffer.Buffer.Length)
                        {
                            bigBuffer = loadbuffer;
                        }
                    }
                }
                else
                {
                    if (size > fileSize)
                    {
                        fileSize = size;
                    }
                }
            }
            else
            {
                Debug.Log("size error " + tableLoader.GetTableName());
            }
        }
        if (bigBuffer == null || fileSize > bigBuffer.Buffer.Length)
        {
            bigBuffer = new ByteArray(fileSize);

        }
        Debug.Log("big size " + bigBuffer.Buffer.Length);
        foreach (var v in _configs)
        {
            var cfg = v.Value;
            var item = v.Value.Loader;//因为共享了buffer所以要先加载
            if (!item.LazyDecode())
            {
                cfg.Buffer = bigBuffer;
                yield return LoadItem(loader, cfg);
            }
        }
        foreach (var v in _configs)
        {
            var cfg = v.Value;
            var item = v.Value.Loader;
            if (item.LazyDecode())
            {
                yield return LoadItem(loader, cfg);
            }
        }
    }
    //加载多语言表
    public IEnumerator LoadLang(ResLoader loader, Action callback)
    {
        if (GameEntry.Table.Lang.LoadSuccess())
        {
            yield break;
        }
        yield return LoadItem(loader, _configs[GameEntry.Table.Lang.GetTableName()]);
        callback?.Invoke();
    }
    private IEnumerator LoadItem(ResLoader loader, TableConfig config)
    {
        yield return null;
        var item = config.Loader;
        var fileName = item.FileName;
        var path = string.Format("Assets/Res/DataTable/{0}.bytes", fileName);
        var asset = loader.LoadAsset(path);
        yield return asset;
        loader.Unload(asset);
        if (asset.Asset is TextAsset text)
        {
            config.Buffer = Utils.Unity.ReadTextAssetToByteArray(text, config.Buffer);
            config.Buffer.Clear();
            item.ReadHeader(config.Buffer);
            while (item.TryDecode() > 0)
            {
                yield return null;
            }
            LoadCount++;
        }
        else
        {
            Debug.LogError("load file error " + path);
        }
    }
    private class TableConfig
    {
        public IDataTableLoader Loader;
        public int Size;
        public ByteArray Buffer;
    }
}